+2007-01-19 Robert Ă–gren <gtk@roboros.com>
+
+ Fix for bug #143460 - missed tablet clicks on Windows
+
+ * gdk/win32/gdkinput-win32.c (_gdk_input_wintab_init_check):
+ Request absolute reporting of tablet button state, and cut down
+ the packet queue size a bit.
+ (_gdk_input_other_event): Change button state handling
+ accordingly. Also drop the no longer necessary code that detects
+ missed clicks/releases for button 1. The switch to absolute button
+ state should prevent missed events for all buttons. Additionally,
+ swap button 2 and 3.
+ (_gdk_input_grab_pointer): Don't reset button_state, that will only
+ cause a new press event as soon as the next tablet packet arrives.
+
2007-01-19 Tor Lillqvist <tml@novell.com>
Build Wintab support always on Windows. Don't require the Wintab
#include "gdkinput-win32.h"
#define PACKETDATA (PK_CONTEXT | PK_CURSOR | PK_BUTTONS | PK_X | PK_Y | PK_NORMAL_PRESSURE | PK_ORIENTATION)
-#define PACKETMODE (PK_BUTTONS)
+/* We want everything in absolute mode */
+#define PACKETMODE (0)
#include <pktdef.h>
#define DEBUG_WINTAB 1 /* Verbose debug messages enabled */
* with a smaller queue size.
*/
GDK_NOTE (INPUT, g_print("Attempting to increase queue size\n"));
- for (i = 128; i >= 1; i >>= 1)
+ for (i = 32; i >= 1; i >>= 1)
{
if ((*p_WTQueueSizeSet) (*hctx, i))
{
PACKET packet;
gint k;
gint x, y;
+ guint translated_buttons, button_diff, button_mask;
+ /* Translation from tablet button state to GDK button state for
+ * buttons 1-3 - swap button 2 and 3.
+ */
+ static guint button_map[8] = {0, 1, 4, 5, 2, 3, 6, 7};
if (event->any.window != wintab_window)
{
g_assert (k == gdkdev->info.num_axes);
- if (HIWORD (packet.pkButtons) != TBN_NONE)
+ translated_buttons = button_map[packet.pkButtons & 0x07] | (packet.pkButtons & ~0x07);
+
+ if (translated_buttons != gdkdev->button_state)
{
+ /* At least one button has changed state so produce a button event
+ * If more than one button has changed state (unlikely),
+ * just care about the first and act on the next the next time
+ * we get a packet
+ */
+ button_diff = translated_buttons ^ gdkdev->button_state;
+
/* Gdk buttons are numbered 1.. */
- event->button.button = 1 + LOWORD (packet.pkButtons);
+ event->button.button = 1;
- if (HIWORD (packet.pkButtons) == TBN_UP)
+ for (button_mask = 1; button_mask != 0x80000000;
+ button_mask <<= 1, event->button.button++)
+ {
+ if (button_diff & button_mask)
+ {
+ /* Found a button that has changed state */
+ break;
+ }
+ }
+
+ if (!(translated_buttons & button_mask))
{
event->any.type = GDK_BUTTON_RELEASE;
masktest = GDK_BUTTON_RELEASE_MASK;
- gdkdev->button_state &= ~(1 << LOWORD (packet.pkButtons));
}
else
{
event->any.type = GDK_BUTTON_PRESS;
masktest = GDK_BUTTON_PRESS_MASK;
- gdkdev->button_state |= 1 << LOWORD (packet.pkButtons);
}
+ gdkdev->button_state ^= button_mask;
}
else
{
GDK_NOTE (EVENTS_OR_INPUT,
g_print ("WINTAB motion: %g,%g\n",
event->motion.x, event->motion.y));
-
- /* Check for missing release or press events for the normal
- * pressure button. At least on my ArtPadII I sometimes miss a
- * release event?
- */
- if ((gdkdev->pktdata & PK_NORMAL_PRESSURE
- && (event->motion.state & GDK_BUTTON1_MASK)
- && packet.pkNormalPressure <= MAX (0, (gint) gdkdev->npbtnmarks[0] - 2))
- || (gdkdev->pktdata & PK_NORMAL_PRESSURE
- && !(event->motion.state & GDK_BUTTON1_MASK)
- && packet.pkNormalPressure > gdkdev->npbtnmarks[1] + 2))
- {
- GdkEvent *event2 = gdk_event_copy (event);
- if (event->motion.state & GDK_BUTTON1_MASK)
- {
- event2->button.type = GDK_BUTTON_RELEASE;
- gdkdev->button_state &= ~1;
- }
- else
- {
- event2->button.type = GDK_BUTTON_PRESS;
- gdkdev->button_state |= 1;
- }
- event2->button.state = ((gdkdev->button_state << 8)
- & (GDK_BUTTON1_MASK | GDK_BUTTON2_MASK
- | GDK_BUTTON3_MASK | GDK_BUTTON4_MASK
- | GDK_BUTTON5_MASK))
- | key_state;
- event2->button.button = 1;
- GDK_NOTE (EVENTS_OR_INPUT,
- g_print ("WINTAB synthesized button %s: %d %g,%gg\n",
- (event2->button.type == GDK_BUTTON_PRESS ?
- "press" : "release"),
- event2->button.button,
- event2->button.x,
- event2->button.y));
- _gdk_event_queue_append (display, event2);
- }
}
return TRUE;
{
x_grab_window = NULL;
tmp_list = _gdk_input_devices;
+#if 0
while (tmp_list)
{
gdkdev = (GdkDevicePrivate *)tmp_list->data;
tmp_list = tmp_list->next;
}
+#endif
}
return GDK_GRAB_SUCCESS;